/* ========================================================================= */
/* ------------------------------------------------------------------------- */
/*!
  \file			ETSubItem.h
  \date			september 2011
  \author		TNick

  \brief		Contains the definition for ETSubItem class


  Copyright (c) 2011, Nicu Tofan
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
 * Neither the name of the copyright holder nor the
   names of its contributors may be used to endorse or promote products
   derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. IN NO EVENT SHALL NICU TOFAN BE LIABLE FOR ANY
 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
#ifndef __ETSUBITEM_INC__
#define __ETSUBITEM_INC__
//
//
//
//
/*  INCLUDES    ------------------------------------------------------------ */

#include	<main.h>

class		ETI_CplxTxt;
class		ETSheetView;
class		ETSheet;

#include	<QFont>
#include	<QBrush>
#include	<QPointF>
#include	<QRectF>
#include	<QColor>
#include	<QPainter>
#include	<QKeyEvent>
#include	<QDomElement>

#include	<generic/cc_l2d.h>

/*  INCLUDES    ============================================================ */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */

/// class representing the common interface exposed by all sub-items of a ETI_CplxTxt
/**
*	Sub-items are separate units that share a common interface despite
*	various levels of complexity. Sub-items may contain other sub-items,
*	may display text, symbols or other elements.
*
*	\section create_destroy Creating and deleting sub-items
*	Sub-items are created either from direct user action, when new commer
*	is placed at current cursor position, and indirectly, when a new
*	ETI_CplxTxt item is created or when a certain key (+, -, /) is pressed
*	while editing an existing sub-item.
*
*	The constructor of an sub-item simply brings the internal data in a known
*	state. All further initialization is performed by the caller, depending
*	on particular case. This extends to items inheriting from ETSubItem.
*
*	The destructor currently has no assignment as the class does not dynamic
*	memory allocation. It also does not extract itself from the parent chain
*	and does not trigger an update of the parent item.
*
*	\section relations Logic relations
*	Each ETSubItem belongs to an unidimensional chain. As such, it keeps
*	track of it's predecessor (retrieved via prev() function) and of
*	it's successor (and one may use next() to find the successor). The
*	functions return NULL if the item is last or first in the chain.
*
*	The sub-items keep a pointer and a flag to keep track of their parents.
*	A sub-item that returns true for isTopLevel() will store internally
*	a pointer to the ETI_CplxTxt hosting this sub-item. This may be retrieved
*	by calling fatherCplx(), but be aware that, for sub-items parented in
*	other sub-items, this can be costly, as the entire parent-son chain
*	needs to be iterated to find top-level sub-item.
*
*	Eventual sub-item parent may be found using fatherSubI(), that returns NULL
*	for items that have isTopLevel() true.
*
*	setFather() is not intended for re-parenting. In fact, this capability
*	is not implemented, yet. The function only stores the provided pointer
*	and sets the flags according to the type. It does not inform the
*	parent, it does not trigger a recompute in the parent and nothing
*	that like.
*
*	\section coordinates The coordinate system. Reference point.
*	Each sub-item must define it's own reference point. This may be placed
*	anywhere, both inside or outside the area it actually uses (may be
*	outside it's bounding box). All elements are represented in this coordinate
*	system. The ETSubItem is the only one that is aware of the location of it
*	inside it's box.
*
*	The parent of the sub-item stores a single value to indicate the position.
*	This value represents the X (horizontal) or Y position of the reference point
*	expressed in parent's coordinate system and may be retrieved by using
*	posX() function. The parent that will place all sub-items
*	in a row to the same Y (vertical) position has no need to store
*	that in each item. This value is the only one that is an exception to
*	previously mentioned rule, at it is expressed in parent's coordinate system.
*	Parent may change the value using setPosX().
*
*	\section dimensions Dimensions. Bounding box.
*	One important feature of an ETSubItem is the ability to report it's bounding
*	box in local coordinates (relative to the \ref coordinates "reference point"
*	which is considered o have the position [0, 0]). Converting the
*	bounding box to parent's coordinate system simply means translating
*	reported boundingBox() from [0, 0] to the position that parent stores.
*
*	The bounding box that is reported via boundingBox() encompasses
*	all child sub-items and own graphical elements.
*
*	A set of functions is used to mark sub-items that need to be recomputed
*	(those that had suffered changes that modifies their bounding box
*	and the parents of those items) and recompute() will actually get the
*	size of this item and of all it's kids. Namelly, setSizeDirty() and
*	resetSizeDirty() mark or remove the mark on an item for full re-computation.
*	The item is requested that, on next call to recompute(), it should
*	determine it's bounding box from real elements (font, string) as the one
*	stored internally does not hold meaningful values anymore. All kids
*	of this sub-item must do the same. setKidSizeDirty() and resetKidSizeDirty()
*	act similarly on the flag that marks the sub-item as having kids with
*	dimensions changed. The item who's flag is set did not suffered a change,
*	so internal elements (like it's own text box) does not need to be recomputed.
*	The flags are reset by the recompute() function and may be querried
*	using isSizeDirty() and isKidSizeDirty().
*
*	\section text_characteristics Apparence (font, color)
*	Each sub-item is able to display itself using a different font and color.
*	To prevent unnecessary font changes during the paint process, a flag is used
*	to tell if font change is actually required or the font inherited by the
*	parent is good enough.
*
*	To query a sub-item that inherits from ETSubItem about it's font use
*	font() function. setFont() will save the provided font inside the item
*	and will mark the sub-item (with Flags::SIZE_DIRTY)
*	and all it's parents (with Flags::KID_SIZE_DIRTY) as "dirty". However,
*	during setFont(), the parent ETI_CplxTxt and eventual parent sub-items
*	are not updated dimensionally to reflect (eventual) change in size.
*	To do so, the caller needs to explicitly call ETI_CplxTxt::recompute().
*
*	Color for the sub-item may be found using color() function. To change the
*	color use setColor(), but be aware that the parent ETI_CplxTxt item
*	is not updated. The caller needs to do that itself.
*
*	Both the color and the font may be directly used or inherited from
*	the parent. To find which situation apply, use inheritsFont() and
*	inheritsColor(), which return true if respective element is inherited.
*
*	\section painting Drawing. Visual clues.
*	When an paint event occurs in ETI_CplxTxt, the item will iterate all it's
*	sub-items and ask them to paint themselves with an paint() call.
*	At that point, the item is required to call prePaint(), then do it's
*	drawing, then call postPaint().
*
*	A crucial element in painting sub-items is PaintData structure. Inside
*	paint() function the sub-item will create a local PaintData structure
*	that is initialized with the elements it knows.
*
*	prePaint() function does initialization for the paint independent of
*	the type of sub-item. If the item uses a particular font, different
*	from what it's parent uses, it will select new font. Similar changes
*	are made for the color to be used. Visual clues regarding the background
*	of the sub-item (the bounding box) may be drawn in future implementations.
*	Inside prePaint(), bounding box is computed and saved in painter coordinates.
*
*	postPaint() draws visual clues about the sub-item on top of already painted
*	item (like position of the cursor) and restores the state of the painter
*	regarding the font and color.
*
*	The cursor is presented during the postPaint()and is represented by a
*	horizontal line that stretches on entire bottom base and a vertical line
*	placed either along the left side or along the right side.
*
*	\section def_state Item statuses
*	The class offers the ability to track the initialized / uninitialized state
*	of an item using isInitialised(). A class inheriting from ETSubItem may
*	set the state using either setInitialised() or setUninitialised(). When
*	a new instance is created it marks itself as being in default state. These
*	functions do not change any other state except the flags. This functionality
*	is intended for the class inheriting this one, not for external use.
*
*	\section navigation Navigation
*	Navigation refers to changing the current sub-item in a view using mouse
*	and the keyboard. Functions involved in this process do not trigger
*	a repaint. The caller (ETSheetView::keyPressEvent(), for example) is
*	required to update the item it send the event to and, possibly, the new
*	current item, if the action changed it.
*
*	Simple navigation using keyboard's up, down, left and right keys is
*	forwarded from the ETSheetView to current sub-item. If there is no sub-item
*	made current one present in current view is chosen. The sub-item receives
*	navigation signals with it's navKey() function, where the arguments are the
*	viewport that is sending the signal and the key. navKey() is virtual and
*	each inheriting class is required to implement it. The sub-item receiving
*	the call is guaranteed to be the current sub-item in the viewport. Based
*	on it's internal structure and current position (left or right) of the
*	cursor the item either marks one of it's kids as current, moves the
*	position of the cursor from one side to the other, or dispatches the
*	call to one of the navLeave__ functions.
*
*	ETSubItem manages the navigation at generic level using a set of four
*	functions for four directions. These are intended to be called by
*	navKey() of specific items. navLeaveLeft() and navLeaveRight()
*	selects a sibling (to the right (next) or to the left (previous) ). If there
*	is none, the parent is made current with the cursor on the side of the move.
*	If the item is at the top level, the viewport is requested to select another
*	ETI_CplxTxt item.
*
*	navLeaveBtm() and navLeaveTop() work in a sensible different way. Top
*	level sub-items recieving the event will also request the viewport to
*	select other ETI_CplxTxt items, but any other sub-item that has a parent
*	will request it's parent to select another sub-item using kidNavReq_down()
*	or kidNavReq_up(). Only if the parent finds no kid to select (because
*	it's a simple one or current sub-item is near the edge) the parent itself
*	is selected.
*
*	Here is the logic tree using function names:
*	- ETSheetView::keyPressEvent()
*	        - navKey()
*	                - navLeaveTop()
*	                        - ETSheetView::navLeaveTop()
*	                - navLeaveBtm()
*	                        - ETSheetView::navLeaveBtm()
*	                - navLeaveLeft()
*	                        - ETSheetView::navLeaveLeft()
*	                - navLeaveRight()
*	                        - ETSheetView::navLeaveRight()
*
*	                        - ETSheetView::setCurrentSubI()
*
*	                - ETSheetView::setSelLeft()
*	                - ETSheetView::setSelRight()
*
*
*	\section save_load      Saving and loading from xml file
*	All classes that inherit from ETSubItem are required to implement
*	saveXML() that is used by the parent (a ETI_CplxTxt or another ETSubItem)
*	to save that particular instance. The implementation of saveXML() must make
*	use of saveXMLCmn() to save common properties for all sub-items that are
*	managed by this class.
*
*	Loading an sub-item starts with loadXMLByType(). It looks inside the DOM
*	element it is provided with for a type and, when found, asks the proper
*	class to create an instance based on the properties that are stored
*	in the node. For this purpose, all inheritant classes must be equipped with
*	a static member named \b loadXML. Similarly to saveXMLCmn(), inheritants are
*	requested to call loadXMLCmn() from within their \b loadXML.
*
*	The format of the file that is saved follows the guidance in
*	<a href="https://code.google.com/p/equtemper/source/browse/trunk/doc/example.xml">
*	example.xml</a> that is located in
*	<a href="https://code.google.com/p/equtemper/source/browse/trunk/doc">doc</a>
*	subfolder.
*
*/
class ETSubItem : public CC_L2D		{

	//
	//
	//
	//
	/*  DEFINITIONS    ----------------------------------------------------- */

	friend class ETI_CplxTxt;
	friend class ETSheetView;

	friend class ETSI_Fract;
	friend class ETSI_HText;
	friend class ETSI_Integ;
	friend class ETSI_Lim;
	friend class ETSI_LogicAc;
	friend class ETSI_Matrix;
	friend class ETSI_Radic;
	friend class ETSI_SText;
	friend class ETSI_Sum;
	friend class ETSI_Root;
	friend class ETSI_Rows;



#define	DDHC_SUBITEM_VARS	\
	DDHC_VARIABLE(itm_font)	\
	DDHC_VARIABLE(itm_col)	\
	DDHC_VARIABLE(itm_pen)	\
	DDHC_VARIABLE(bbox)		\
	DDHC_VARIABLE(flg)		\
	DDHC_VARIABLE(fth.fth_cplx)		\
	DDHC_VARIABLE(fth.fth_sub_i)	\
	DDHC_VARIABLE(x_pos)




	/// structure used with paint opperations to pass arguments arround
	struct	PaintData		{
		/* input from caller, valid as long as the structure lives */
		ETSheetView *		vp;			/**< the viewport where we're drawing*/
		QPainter *			painter;	/**< painter object*/
		QPointF				pt_ref;		/**< the position of the reference
point in painter's (actually in scene) coordinate system */

		/* only valid after the call to prePaint */
		QRectF				t_box;		/**< bounding box for the item in
painter's (actually in scene) coordinate system */

		PaintData(ETSheetView * i_vp, QPainter * i_painter, QPointF i_pt_ref)
		{ vp = i_vp; painter = i_painter; pt_ref = i_pt_ref; }
	};



	/// structure used with the hit test function to pass informations arround
	struct		HtData		{

		QPointF		ck_pt;		/**< point that is searched in ETI_CplxTxt
item coordinates; this must be filled by the caller */

		ETSubItem * it_hitted;	/**< the final item that was hit */

		bool		true_hit;	/**< set to true if the \b it_hitted was
hit inside an active area (like over the text) or to false if the point
is inside the bounding box of this item but over an unused area */

		QPointF		ref_pt;		/**< the coordinates of the reference point
for the item that was hit in ETI_CplxTxt item coordinates */

		QRectF		rct_bbx;	/**< the bounding box of this item in
ETI_CplxTxt item coordinates */
		QRectF		rct_cache;	/**< used to avoid storing the data on the stack;
It is used by the iterative process to store converted coordinates; it is
meaningless to the caller */

		quint64		int_data;	/**< each sub-item may save whatever data
it wishes in this field*/

		HtData(QPointF pt_to_ck)
		{
			ck_pt = pt_to_ck;
			it_hitted = NULL;
			true_hit = false;
			rct_bbx.setCoords(0,0,0,0);
			ref_pt.setX(0); ref_pt.setY(0);
			int_data = 0;
		}
	};




	/// one bit switches
	enum Flags		{
		NOFLAGS = 0,

		SIZE_DIRTY = 0x00000001,		/**< set when an item's characteristics
that participate in determining the dimensions (bounding box) have chganged.
It is set by setFont(), for example. */
		KID_SIZE_DIRTY = 0x00000002,	/**< set in all parents (up to the top
one) of an item who's SIZE_DIRTY flag has been set. */


		CHILD_ITEM = 0x00000004,		/**< this item is not placed at the
top level (fth_sub_i is valid) */


		FONT_MOD = 0x00000008,			/**< the font stored inside this item
is different than the one it's parent has, thus it is crucial to change
the font used when this item's being painted */
		COL_MOD = 0x00000010,			/**< the color stored inside this item
is different than the one it's parent has, thus it is crucial to change
the color used when this item's being painted */
		PEN_MOD = 0x00000020,			/**< the pen stored inside this item
is different than the one it's parent has, thus it is crucial to change
the pen used when this item's being painted */


		DEFAULT_STATE = 0x00000040,		/**< this sub-item is in uninitialised
state. It may present text for the user, for example, but it does not have
a real value. Classes that inherit from ETSubItem are not required to
assign a meaning to this flag.*/


		SELECTED = 0x00000080,			/**< the item is visually selected. This
is not the same thing as being current item in a viewport.*/



		SBI_FLAGS = 0x0000FFFF,			/**< mask for the flags reserved for
  ETSubItem. The rest of the places may be freely used by classes inheriting
  ETSubItem class.*/

		INH_FLAGS = 0xFFFF0000,			/**< mask for the flags reserved for
  classes inheriting ETSubItem class.*/


		MAX_FLAGS
	};


public:

	/// enumeration that tells the types of sub-items we know about
	enum		SIType		{
		TYROOT = 0,
		TYROWS,
		TYFRACT,
		TYHTEXT,
		TYINTEG,
		TYLIM,
		TYLOGICAC,
		TYMATRIX,
		TYRADIC,
		TYSTEXT,
		TYSUM,
		TYMAX
	};

	/*  DEFINITIONS    ===================================================== */
	//
	//
	//
	//
	/*  DATA    ------------------------------------------------------------ */

protected:



	/// the default font that is used to paint this item
	QFont		itm_font;

	/// color used to paint this item
	QColor		itm_col;

	/// the rgb used to paint text, draw lines, ...
	QRgb		itm_pen;

	/// the boundingg box in local coordinates
	QRectF		bbox;

	/// various 1 bit switches
	Flags		flg;

	/// pointer to parent sub-item or ETI_CplxTxt if at top level
	union	{
		/// the hosting item, used if this ETSubItem is at top level
		ETI_CplxTxt *	fth_cplx;
		/// parent sub-item
		ETSubItem *		fth_sub_i;
	} fth;

	/// position (in parent coordinate system)
	qreal		x_pos;



	/*  DATA    ============================================================ */
	//
	//
	//
	//
	/*  FUNCTIONS    ------------------------------------------------------- */

public:

	/// constructor
	/**
   *	The constructor of an sub-item simply brings the internal data in a known
   *	state. All further initialization is performed by the caller, depending
   *	on particular case.  This extends to items inheriting from ETSubItem.
   */
	ETSubItem			( void );


	/// destructor
	/**
  *	The destructor currently has no assignment as the class does not dynamically
  *	memory allocation. It also does not extract itself from the parent chain
  *	and does not tigger an update of the parent item.
  */
	virtual				~ETSubItem		( void );


	/// removes the item from the ETI_CplxTxt item; may tigger an update
	/**
   *	If multiple sub-items belonging to the
   *	same ETI_CplxTxt item have to be changed, \b b_recomp parameter may be
   *	set to false to prevent the function from recomputing all sub-items
   *	involved. The caller is responsible for calling ETI_CplxTxt::recompute()
   *	when all changes were applied.
   */
	void				remove			(
		bool			b_recomp = true	/**< should the ETI_CplxTxt
		item be redrawn?*/
		);


	/// informed when a direct kid is about to be removed
	/**
	*	The sub-item is only required to remove the kid from internal
	*	chain if it has one. It is intended to be used by complex
	*	sub-items that may host other sub-items.
	*/
	virtual void		ackRemoveKid	(ETSubItem * kid) { Q_UNUSED(kid); }






	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
	/** @name Apparence (font, color)    */
	//@{
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */


	/// default font
	QFont				font			( void ) const;


	/// set default font
	void				setFont			(QFont new_font);


	/// tell if the sub-item inherits the font or uses it's own
	bool				inheritsFont	( void ) const
	{ return ((flg & FONT_MOD) == 0); }


	/// default color
	QColor				color			( void ) const
	{ return itm_col; }


	/// set default color
	void				setColor		(QColor new_color);


	/// tell if the sub-item inherits the font or uses it's own
	bool				inheritsColor	( void ) const
	{ return ((flg & COL_MOD) == 0); }


	/// default pen
	QColor				pen			( void ) const
	{ return itm_pen; }


	/// set default color
	void				setPen		(QRgb new_color);


	/// tell if the sub-item inherits the font or uses it's own
	bool				inheritsPen	( void ) const
	{ return ((flg & PEN_MOD) == 0); }


	//@}
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */




	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
	/** @name Dimensions. Bounding box.    */
	//@{
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */


	/// the bounding box
	QRectF				boundingBox		( void ) const
	{ return bbox; }

	/// only the width of this item
	qreal				width			( void ) const
	{ return bbox.width(); }

	/// only the height of this item
	qreal				height			( void ) const
	{ return bbox.height(); }





public:
	/// tell if this item's own elements were changed */
	bool		isSizeDirty				( void ) const
	{ return ((flg & SIZE_DIRTY) != 0); }


	/// tell if this item's kids were changed */
	bool		isKidSizeDirty			( void ) const
	{ return ((flg & KID_SIZE_DIRTY) != 0); }

	/// tell if any of the sizeflags are set
	bool		requireRecompute		( void ) const
	{ return ((flg & (KID_SIZE_DIRTY | SIZE_DIRTY)) != 0); }

protected:

	/// marks this item and all it's parents as being required to be recomputed
	void		setSizeDirty			(ETI_CplxTxt ** tp_fth = NULL);


	/// resets the flag marking the sub-item as being required to be recomputed
	void		resetSizeDirty			( void )
	{ flg = (Flags)(flg & (~SIZE_DIRTY)); }


	/// marks this sub-item as having kids required to be recomputed
	void		setKidSizeDirty			( void )
	{ flg = (Flags)(flg | KID_SIZE_DIRTY); }


	/// resets the flag marking the sub-item as having kids required to be recomputed
	void		resetKidSizeDirty		( void )
	{ flg = (Flags)(flg & (~KID_SIZE_DIRTY)); }


	/// resets all the flags concearning size
	void		resetSizeFlags			( void )
	{ flg = (Flags)(flg & (~(KID_SIZE_DIRTY | SIZE_DIRTY))); }


	/// get the bounding box of this item
	/**
   *	The function may or may not honor the flags representing the "dirty"
   *	state of that item regarding it's characteristics depending on
   *	\b b_full argument (when true the flags are ignored)
   */
	virtual void	recompute			(bool b_full) = 0;


	//@}
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */



protected:


	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
	/** @name The coordinate system. Reference point.    */
	//@{
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */


	/// tell the position of this item in parent's coordinate system
	qreal				posX			( void ) const
	{ return x_pos; }


	/// set the position of this item in parent's coordinate system
	void				setPosX			(qreal new_X)
	{ x_pos = new_X; }


	//@}
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */




public:

	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
	/** @name Logic relations    */
	//@{
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */


	/// return next item
	inline ETSubItem*	next			( void )
	{ return (ETSubItem*)CC_L2D::next(); }


	/// return previous item
	inline ETSubItem*	prev			( void )
	{ return (ETSubItem*)CC_L2D::prev(); }


	/// tell if this element is top level or not
	bool				isTopLevel		( void ) const
	{ return ((flg & CHILD_ITEM) == 0); }


	/// set the father item
	inline void			setFather		(ETSubItem * new_fth)
	{ fth.fth_sub_i = new_fth; flg = (Flags)(flg | CHILD_ITEM); }


	/// get the father item
	inline ETSubItem *	fatherSubI		( void ) const
	{ if (isTopLevel()) return NULL; return fth.fth_sub_i; }


	/// set the father complex text
	inline void			setFather		(ETI_CplxTxt * new_fth)
	{ fth.fth_cplx = new_fth; flg = (Flags)(flg & (~CHILD_ITEM)); }


	/// get the ETI_CplxTxt father (complex text)
	ETI_CplxTxt  *		fatherCplx		( void ) const;


	//@}
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */


protected:

	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
	/** @name Item statuses    */
	//@{
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */

	/// marks this item as having a "true" value
	void		setInitialised			( void )
	{ flg = (Flags)(flg & (~DEFAULT_STATE)); }

	/// marks this item as having no "real" value
	void		setUninitialised		( void )
	{ flg = (Flags)(flg | DEFAULT_STATE); }

	/// tells if the item is in initialised (true) or uninitialised state (false)
	bool		isInitialised			( void ) const
	{ return ((flg & DEFAULT_STATE) == 0); }


	/// visually deselected; this is not the same thing as the current si
	void		deselect				(
		ETI_CplxTxt **	fth_ = NULL,	/**< variable that stores a pointer to father;
if NULL is provided, the function will use fatherCplx() to find it's parent;
if points to a NULL value, the function will save the parent it finds;
if valid, the pointer is used; no need for a call to fatherCplx() */
		bool			b_redraw = true /**< if set to true, the ETI_CplxTxt
item is redrawn, otherwise the caller is expected to redraw the item itself */
		);

	/// visually selected; this is not the same thing as the current si
	void		select					(
		ETI_CplxTxt **	fth_ = NULL,	/**< variable that stores a pointer to father;
if NULL is provided, the function will use fatherCplx() to find it's parent;
if points to a NULL value, the function will save the parent it finds;
if valid, the pointer is used; no need for a call to fatherCplx() */
		bool			b_redraw = true /**< if set to true, the ETI_CplxTxt
item is redrawn, otherwise the caller is expected to redraw the item itself */
		);

	/// tell if visually selected; this is not the same thing as the current si
	bool		isSelected				( void ) const
	{ return ((flg & SELECTED) != 0); }



	//@}
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */



protected:


	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
	/** @name Drawing. Visual clues.    */
	//@{
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */


	/// paint the element on provided surface
	/**
   *	When an paint event occurs in ETI_CplxTxt, the item will iterate all it's
   *	sub-items and ask them to paint themselves with an paint() call.
   *	At that point, the item is required to call prePaint(), then do it's
   *	drawing, then call postPaint().
   *
   *	A crucial element in painting sub-items is PaintData structure. Inside
   *	paint() function the sub-item will crete a local PaintData structure
   *	initialised with the elements it knows
   */
	virtual void		paint			(
		ETSheetView *		vp,		/**< represents the viewport where
		 the painting takes place */
		QPainter *			painter,/**< we're required to draw on
		 this object */
		QPointF				pt_ref	/**< the coordinates of the reference
		 point of this sub-item in \b painter coordinate system */
		) = 0;


	/// items need to call this function before proceeding with their painting
	/**
   *	The function does initialization for the paint independent of
   *	the type of sub-item. If the item uses a particular font, different
   *	from what it's parent uses, it will select new font. Similar changes
   *	are made for the color to be used. Visual clues regarding the background
   *	of the sub-item (the bounding box) may be drawn in future implementations.
   *	Inside prePaint(), bounding box is computed and saved in painter coordinates.
   */
	void				prePaint			(
		PaintData *			pd
		);


	/// items need to call this function after they've done their painting
	/**
   *	postPaint() draws visual clues about the sub-item on top of already painted
   *	item (like position of the cursor) and restores the state of the painter
   *	regarding the font and color.
   */
	void				postPaint			(
		PaintData *			pd
		);


	//@}
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */




	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
	/** @name Navigation    */
	//@{
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */

public:

	/// recieves navigation keys
	void		navKey				(
		ETSheetView *		vp,
		Qt::Key 			key
		);


//	/// recieves navigation keys
//	virtual void		navKey				(
//		ETSheetView *		vp,
//		Qt::Key 			key
//		) = 0;



protected:

	/// the item is left from the top side
	void				navLeaveTop			(
		ETI_CplxTxt *	fth,
		ETSheetView *	vp
		);

	/// the item is left from the bottom side
	void				navLeaveBtm			(
		ETI_CplxTxt *	fth,
		ETSheetView *	vp
		);

	/// the item is left from the top side
	void				navLeaveLeft		(
		ETI_CplxTxt *	fth,
		ETSheetView *	vp
		);

	/// the item is left from the bottom side
	void				navLeaveRight		(
		ETI_CplxTxt *	fth,
		ETSheetView *	vpa
		);


	/// used by kids to request a move up
	/**
   *	If the parent can't move the selection as there is no
   *	kid above the caller, it should return false
   */
	virtual bool		kidNavReq_up		(
			ETSheetView * vp, ETSubItem * kid)
	{ Q_UNUSED(vp); Q_UNUSED(kid); return false; }


	/// used by kids to request a move down
	/**
   *	If the parent can't move the selection as there is no
   *	kid below the caller, it should return false
   */
	virtual bool		kidNavReq_down		(
			ETSheetView * vp, ETSubItem * kid)
	{ Q_UNUSED(vp); Q_UNUSED(kid); return false; }


	/// the sub-item is to become current sub-item in viewport
	void				makeCurrent			(ETSheetView * vp);


	//@}
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */




	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
	/** @name Others    */
	//@{
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */


protected:

	/// called to determine the sub-item that was hit
	/**
   *	The items called with this function are already guaranteed to contain
   *	the point, as the caller is required to check the point before against
   *	sub-items bounding box that is publicly available.
   *
   *	The item checks if any internal kids are containing the point and, if so,
   *	forwards the call to that kid. The final item that has determined that
   *	the point is inside it's box shall save it's informations in \b h_data.
   *
   *
   *
   */
	virtual void		hitTest		(HtData * h_data) = 0;





public:

	/// identifies the type of the sub-item
	virtual SIType		type		( void ) const = 0;


	/// get the bounding box of this item represented in the item
	/**
	*	The function will compute the bounding box of the sub-item represented
	*	in scene coordinates by iterating the father-son bond up until
	*	the very first root item is found. These are the coordinates in
	*	ETI_CplxTxt system.
	*/
	QRectF				boxInItem	(ETI_CplxTxt ** fth) const;


	/// get the bounding box of this sub-item represented in the scene
	/**
	*	The function will compute the bounding box of the sub-item represented
	*	in scene coordinates by iterating the father-son bond up until
	*	the very first root item is found. These are the coordinates in
	*	ETI_CplxTxt system that are transformed to scene coordinates.
	*/
	QRectF				boxInScene	(ETI_CplxTxt ** fth) const;


	/// returns the position of the reference point given child in this item's coordinates
	/**
	*	This function is intended for complex items; the argument needs to be a
	*	direct kid. For simple items the default implementation will do.
	*
	*	The function is not required to check if the provided item is trully a kid,
	*	as it is assumed the caller has already done that.
	*/
	virtual QPointF		subIRefPt	(const ETSubItem * p_kid) const;


	//@}
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */




	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
	/** @name Save and load	*/
	//@{
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */

public:


	/// updates the properties of specified item based on DOM element's content
	static void			loadXMLCmn			(
		ETSubItem *			item,
		QDomElement			dom_e
		);


	/// updates the properties of specified item based on DOM element's content
	static ETSubItem *	loadXMLByType			(
		QDomElement			dom_e
		);


	/// saves the properties of this item to provided DOM element
	/**
	*	Internally, the inherited class needs to call saveXMLCmn()
	*	to save common properties hosted by the ETSubItem class
	*/
	virtual void		saveXML			(
		QDomElement			dom_e
		) = 0;


protected:

	/// saves common properties to provided DOM element
	void				saveXMLCmn		(
		QDomElement			dom_e
		);

	//@}
	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */





	/*  FUNCTIONS    ======================================================= */
	//
	//
	//
	//

};	/*	class ETSubItem	*/

/*  CLASS    =============================================================== */
//
//
//
//
#endif // __ETSUBITEM_INC__
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
